<template>
  <!-- 搜索 -->
  <t-card :bordered="false">
    <!-- 自定义搜索 -->
    <custom-search ref="customSearchRef" v-slot="{ params }" @submit="handleInitTable">
      <t-col :span="3">
        <t-form-item label="文件路径" name="path">
          <t-input
            v-model:value="params.path"
            placeholder=""
            clearable 
          />
        </t-form-item>
      </t-col>
      <t-col :span="3">
        <t-form-item label="文件类型" name="type">
          <t-input
            v-model:value="params.type"
            placeholder=""
            clearable
          />
        </t-form-item>
      </t-col>
      <t-col :span="3">
        <t-form-item label="创建时间" name="createTime">
          <t-date-range-picker
            allow-input
            v-model:value="params.createTime"
            clearable
            enable-time-picker
            placeholder=" "
            style="width: 100%"
          />
        </t-form-item>
      </t-col>
    </custom-search>
    <!-- 自定义表格 -->
    <custom-table
      ref="customTableRef"
      row-key="id"
      :columns="columns"
      :api="fileCRUD.page"
      column-controller-key="fileList"
    >
    <template #topContent>
        <div style="margin-bottom: var(--td-comp-margin-xxl)">
          <t-button  @click="openForm">
            上传文件
          </t-button>
        </div>
      </template>
      <template #size="{ row }">
        {{ fileSizeFormatter(row.size) }}
      </template>
      <template #content="{ row }">
        <image-viewer v-if="row.type.includes('image')" :images="[row.url]" width="80px" height="80px" />
        <t-link
          v-else-if="row.type.includes('pdf')"
          theme="primary"
          :href="row.url"
          target="_blank"
          hover="color"
        >
          预览
        </t-link>
        <t-link
          v-else
          theme="primary"
          :href="row.url"
          target="_blank"
          hover="color"
          download
        >
          下载
        </t-link>
      </template>
      <template #createTime="{ row }">
        {{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
      </template>
      <template #operation="{ row }">
        <t-space>
          <t-popconfirm content="确认要删除该项吗？" @confirm="handleDelete({ id: row.id })">
            <t-link v-permission="['infra:file:delete']" theme="danger"> 删除 </t-link>
          </t-popconfirm>
        </t-space>
      </template>
    </custom-table>

  <!-- 上传弹窗 -->
  <t-dialog
    v-model:visible="dialogVisible"
    header="上传文件"
    :confirm-btn="{ loading: formLoading, content: '确定', onClick: submitFileForm }"
    :cancel-btn="{ content: '取消' }"
  >
    <t-upload
      ref="uploadRef"
      :key="uploadKey"
      v-model:value="fileList"
      :action="uploadUrl"
      :auto-upload="false"
      :data="data"
      :disabled="formLoading"
      :max="1"
      :on-change="handleFileChange"
      :on-error="submitFormError"
      :on-exceed="handleExceed"
      :on-success="submitFormSuccess"
      :custom-request="httpRequest"
      accept="image/*"
      theme="file"
      draggable
      :headers="headers"
    >
      <template #dragContent>
        <div class="upload-drag-content">
          <upload-icon size="48px" />
          <p>将文件拖到此处，或 <span>点击上传</span></p>
        </div>
      </template>
      <template #tip>
        <p class="tip">提示：仅允许导入 jpg、png、gif 格式文件！</p>
      </template>
    </t-upload>
  </t-dialog>
  </t-card>
</template>

<script lang="ts" setup>

import {fileCRUD, getFilePresignedUrl} from '@/api/system/file'
import { useUpload } from '@/components/UploadFile/src/useUpload'
import CustomDialog from '@/components/custom/dialog/index.vue';
import CustomSearch from '@/components/custom/search/index.vue';
import CustomTable from '@/components/custom/table/index.vue';
import ImageViewer from '@/components/image-viewer/index.vue';
import { ref, reactive, onMounted, computed, useTemplateRef } from 'vue'
import {
  SearchIcon,
  RefreshIcon,
  UploadIcon,
} from 'tdesign-icons-vue-next'
import { MessagePlugin, TableCol } from 'tdesign-vue-next';
import dayjs from 'dayjs';
import { useUserStore } from '@/store';

defineOptions({ name: 'InfraFile' })

// 用户仓库
const userStore = useUserStore();
const fileSizeFormatter = (cellValue:any) => {
  const fileSize = cellValue
  const unitArr = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  const srcSize = parseFloat(fileSize)
  const index = Math.floor(Math.log(srcSize) / Math.log(1024))
  const size = srcSize / Math.pow(1024, index)
  const sizeStr = size.toFixed(2) //保留的小数位数
  return sizeStr + ' ' + unitArr[index]
}
const uploadKey = ref(Date.now());
// 请求头
const headers = ref({
  Authorization: `Bearer ${userStore.token}`,
});

// 自定义搜索ref
const customSearchRef = useTemplateRef('customSearchRef');
// 自定义表格ref
const customTableRef = useTemplateRef('customTableRef');

// 处理初始化表格
const handleInitTable = () => {
  const params = { ...customSearchRef.value.params };
  customTableRef.value.initTable(params);
};
// 处理刷新表格
const handleRefreshTable = () => {
  customTableRef.value.refreshTable();
};
onMounted(() => {
  handleInitTable();
});
// 自定义对话框ref
// const customDialogRef = useTemplateRef('customDialogRef');
// // 处理打开对话框
// const handleOpenDialog = (mode: 'create' | 'read' | 'update', params: Record<string, any>) => {
//   customDialogRef.value.open(mode, params);
// };
// 上传相关
const dialogVisible = ref(false) // 弹窗的是否展示
const formLoading = ref(false) // 表单的加载中
const fileList = ref([]) // 文件列表
const data = ref()
const uploadRef = ref<{
  submit: () => void
  clearFiles: () => void
}>();
const { uploadUrl, httpRequest } = useUpload()

// 表格列定义
const columns: TableCol[] = [
  { colKey: 'name', title: '文件名', ellipsis: true },
  { colKey: 'path', title: '文件路径', ellipsis: true },
  { colKey: 'url', title: 'URL', ellipsis: true },
  { colKey: 'size', title: '文件大小', width: 120 },
  { colKey: 'type', title: '文件类型', width: 180 },
  { colKey: 'content', title: '文件内容', width: 110 },
  { colKey: 'createTime', title: '上传时间', width: 180 },
  { colKey: 'operation', title: '操作', width: 100, fixed: 'right' }
]


/** 打开上传弹窗 */
const openForm = () => {
  dialogVisible.value = true
  resetForm()
}

/** 处理上传的文件发生变化 */
const handleFileChange = (file: any) => {
  // data.value.path = file.name
}

/** 提交表单 */
const submitFileForm = () => {
  if (fileList.value.length == 0) {
    MessagePlugin.error('请上传文件')
    return
  }
  uploadRef.value?.submit()
}

/** 文件上传成功处理 */
const submitFormSuccess = () => {
  // 清理
  dialogVisible.value = false
  formLoading.value = false

  fileList.value = [];
  // 提示成功，并刷新
  MessagePlugin.success('新增成功')
  handleInitTable()
}

/** 上传错误提示 */
const submitFormError = (): void => {
  MessagePlugin.error('上传失败，请您重新上传！')
  formLoading.value = false
}

/** 重置表单 */
const resetForm = () => {
  // 重置上传状态和文件
  formLoading.value = false
  uploadKey.value = Date.now();
  fileList.value = [];
}

/** 文件数超出提示 */
const handleExceed = (): void => {
  MessagePlugin.error('最多只能上传一个文件！')
}

/** 删除按钮操作 */
const handleDelete = async (params: Record<string, any>) => {
  fileCRUD
    .delete(params)
    .then(() => {
      MessagePlugin.success('删除成功');
      handleRefreshTable();
    })
    .catch(({ message }) => {
      MessagePlugin.error(message);
    });
}

</script>

<style lang="less" scoped>
.list-card {
  margin-bottom: 16px;
}

.upload-drag-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px;

  p {
    margin-top: 16px;
    color: var(--td-text-color-secondary);

    span {
      color: var(--td-brand-color);
      cursor: pointer;
    }
  }
}

.tip {
  margin-top: 8px;
  color: var(--td-error-color);
  font-size: 12px;
}
</style>
